package com.oig.sys.file.controller;


import com.oig.common.constants.CommonConstants;
import com.oig.common.constants.CommonEnum;
import com.oig.common.exception.BadRequestException;
import com.oig.common.module.SysRequest;
import com.oig.common.module.SysResponse;
import com.oig.common.validator.GroupAdd;
import com.oig.common.validator.GroupChange;
import com.oig.common.validator.GroupEdit;
import com.oig.sys.file.app.IAppFileInfoService;
import com.oig.sys.file.dto.BusFileInfoDto;
import com.oig.sys.file.dto.FileInfoDto;
import com.oig.sys.file.vo.FileInfoVo;
import com.oig.sys.log.annotation.SysLog;
import com.oig.sys.security.util.SecurityUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.List;


@Tag(name = "文件管理")
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/fileInfo")
public class TbFileInfoController {

    private final IAppFileInfoService appFileInfoService;


    //@PreAuthorize("@pms.hasPermission('/fileInfo/add')")
    @SysLog(value="保存业务文件信息",apiUrl="/fileInfo/add")
    @Operation(summary = "保存业务文件信息,业务系统可以直接使用该接口增加文件，也可以单独提柜接口")
    @PostMapping("/add")
    public FileInfoVo addFileInfo(@RequestBody @Validated(GroupAdd.class) FileInfoDto fileInfoDto){
        log.info("add file : {}", fileInfoDto);
        this.setDefCreater(fileInfoDto);
        if (!CommonEnum.RelationType.NIX.getCode().equals(fileInfoDto.getRelationType())){
            if (StringUtils.isBlank(fileInfoDto.getRelationId())){
                throw new BadRequestException("需要关联单据id") ;
            }
        }
        if (!CommonConstants.DEF_MIX_STR.equals(fileInfoDto.getBusinessType())){
            if (StringUtils.isBlank(fileInfoDto.getBusinessOrderId())){
                throw new BadRequestException("需要业务单号") ;
            }
        }
        return this.appFileInfoService.addFileInfo(fileInfoDto) ;
    }

    private void setDefCreater(FileInfoDto fileInfoDto){
        //第三方可能没有ID, 用name判断
        fileInfoDto.setCreateTime(fileInfoDto.getCreateTime() == null ? new Date() : fileInfoDto.getCreateTime());
        if (fileInfoDto.getCreateName()==null){
            fileInfoDto.setCreateId(SecurityUtil.getUserForIfNullBuild().getId());
            fileInfoDto.setCreateCode(SecurityUtil.getUserForIfNullBuild().getCode());
            fileInfoDto.setCreateName(SecurityUtil.getUserForIfNullBuild().getRealName());
        } else {
            fileInfoDto.setCreateId(fileInfoDto.getCreateId());
            fileInfoDto.setCreateCode(fileInfoDto.getCreateCode());
            fileInfoDto.setCreateName(fileInfoDto.getCreateName());
        }
        if (fileInfoDto.getTenantId()==null){
            fileInfoDto.setTenantId(SecurityUtil.getUserForIfNullBuild().getTenantId());
            fileInfoDto.setTenantName(SecurityUtil.getUserForIfNullBuild().getTenantName());
        }
    }

    private void setDefUpdater(FileInfoDto fileInfoDto){
        if (fileInfoDto.getFileUploadName()==null){
            fileInfoDto.setFileUploadId(SecurityUtil.getUserForIfNullBuild().getId());
            fileInfoDto.setFileUploadCode(SecurityUtil.getUserForIfNullBuild().getCode());
            fileInfoDto.setFileUploadName(SecurityUtil.getUserForIfNullBuild().getRealName());
            fileInfoDto.setFileUploadTime(new Date());
        }
        if (fileInfoDto.getLastUpdateName()==null){
            fileInfoDto.setLastUpdateId(SecurityUtil.getUserForIfNullBuild().getId());
            fileInfoDto.setLastUpdateCode(SecurityUtil.getUserForIfNullBuild().getCode());
            fileInfoDto.setLastUpdateName(SecurityUtil.getUserForIfNullBuild().getRealName());
        }
        fileInfoDto.setLastUpdateTime(new Date());
    }

    //@PreAuthorize("@pms.hasPermission('/fileInfo/update')")
    @SysLog(value="更新业务文件信息",apiUrl="/fileInfo/update")
    @Operation(summary = "更新业务文件信息")
    @PostMapping("/update")
    public FileInfoVo updateFileInfo(@RequestBody @Validated(GroupEdit.class) FileInfoDto fileInfoDto){
        log.info("update file : {}", fileInfoDto);
        this.setDefUpdater(fileInfoDto);
        return this.appFileInfoService.updateFileInfo(fileInfoDto) ;
    }


//    @PreAuthorize("@pms.hasPermission('/fileInfo/updateRelationAllFileInfo')")
    @SysLog(value="批量更新业务文件信息",apiUrl="/fileInfo/updateRelationAllFileInfo")
    @Operation(summary = "批量更新业务文件信息")
    @PostMapping("/updateRelationAllFileInfo")
    public List<FileInfoVo> updateRelationAllFileInfo(@RequestBody @Validated(GroupAdd.class) BusFileInfoDto busFileInfoDto){
        log.info("update multi file : {}", busFileInfoDto);
        if (StringUtils.isBlank(busFileInfoDto.getBusinessOrderId()) && StringUtils.isBlank(busFileInfoDto.getRelationId())){
            throw new BadRequestException("主业务单号，关联单号至少要有一个") ;
        }
        if (!CommonConstants.DEF_MIX_STR.equals(busFileInfoDto.getBusinessType())){
            if (StringUtils.isBlank(busFileInfoDto.getBusinessOrderId())){
                throw new BadRequestException("需要业务单号") ;
            }
        }
        if (!CommonEnum.RelationType.NIX.getCode().equals(busFileInfoDto.getRelationType())){
            if (StringUtils.isBlank(busFileInfoDto.getRelationId())){
                throw new BadRequestException("需要关联单据id") ;
            }
        }
        for (FileInfoDto fileInfoDto : busFileInfoDto.getList()){
            if (fileInfoDto.getId()==null){
                this.setDefCreater(fileInfoDto);
            } else {
                this.setDefUpdater(fileInfoDto);
            }
        }
        return this.appFileInfoService.updateRelationAllFileInfo(busFileInfoDto) ;
    }

    //@PreAuthorize("@pms.hasPermission('/fileInfo/delRelationAllFileInfo')")
    @SysLog(value="批量删除文件信息",apiUrl="/fileInfo/delRelationAllFileInfo")
    @Operation(summary = "批量删除文件信息")
    @PostMapping("/delRelationAllFileInfo")
    public SysResponse<String> delRelationAllFileInfo(@RequestBody @Validated(GroupChange.class) BusFileInfoDto busFileInfoDto){
        log.info("del multi file : {}", busFileInfoDto);
        if (StringUtils.isBlank(busFileInfoDto.getBusinessOrderId()) && StringUtils.isBlank(busFileInfoDto.getRelationId())){
            throw new BadRequestException("主业务单号，关联单号至少要有一个") ;
        }
        this.appFileInfoService.delRelationAllFileInfo(busFileInfoDto) ;
        return SysResponse.ok(busFileInfoDto.getRelationId(),"删除成功");
    }


    @PreAuthorize("@pms.hasPermission('/fileInfo/cancel')")
    @SysLog(value="逻辑删除文件记录",apiUrl="/fileInfo/cancel")
    @Operation(summary = "逻辑删除文件记录,不会删除文件")
    @PostMapping("/cancel/{id}")
    public FileInfoVo cancelFileInfo(@PathVariable("id") Integer id){
        log.info("cancel file : {}", id);
        return this.appFileInfoService.cancelFileInfo(id);
    }


    @PreAuthorize("@pms.hasPermission('/fileInfo/del')")
    @SysLog(value="物理删除文件记录",apiUrl="/fileInfo/del")
    @Operation(summary = "物理删除文件记录,同时会删除文件")
    @PostMapping("/del/{id}")
    public SysResponse<Integer> delFileInfo(@PathVariable("id") Integer id){
        log.info("del file : {}", id);
        this.appFileInfoService.delFileInfo(id);
        return SysResponse.ok(id,"删除成功");
    }

    @Operation(summary = "获取文件记录明细信息,目前用于feign调用")
    @PostMapping("/info/{id}")
    public FileInfoVo info(@PathVariable("id") Integer id){
        log.info("get file info : {}", id);
        return this.appFileInfoService.getFileInfo(id);
    }



    @Operation(summary = "查询文件信息,比如根据业务类型，业务单据id查询附件")
    @PostMapping("/list")
    public List<FileInfoVo> list(@RequestBody SysRequest<FileInfoDto> fileInfoRequest){
        log.info("list File Info:{}",fileInfoRequest);
        if (fileInfoRequest.getParamDto()==null){
            throw new BadRequestException("查询参数必须有");
        }
        if (StringUtils.isBlank(fileInfoRequest.getParamDto().getBusinessOrderId()) && StringUtils.isBlank(fileInfoRequest.getParamDto().getRelationId())){
            throw new BadRequestException("必须是按单据查询") ;
        }
        if (StringUtils.isNotBlank(fileInfoRequest.getParamDto().getBusinessOrderId()) && StringUtils.isBlank(fileInfoRequest.getParamDto().getBusinessType())){
            throw new BadRequestException("业务类型必填") ;
        }
        if (StringUtils.isNotBlank(fileInfoRequest.getParamDto().getRelationId()) && StringUtils.isBlank(fileInfoRequest.getParamDto().getRelationType())){
            throw new BadRequestException("关联单据类型必填") ;
        }
        return this.appFileInfoService.queryList(fileInfoRequest).getList();
    }


    @SysLog(value="批量保存业务文件信息",apiUrl="/fileInfo/addBatchFile")
    @Operation(summary = "保存业务文件信息,业务系统可以直接使用该接口增加文件，也可以单独提柜接口")
    @PostMapping("/addBatchFile")
    public List<FileInfoVo> addBatchFile(@RequestBody @Validated(GroupAdd.class) List<FileInfoDto> fileInfoDtoList){
        log.info("fileInfoDtoList file : {}", fileInfoDtoList);
        return this.appFileInfoService.addBatchFile(fileInfoDtoList) ;
    }
}
